'use strict';
//////////////////////////////////////////////////////////////////////////////
// JSON格式化 项目使用
// =====================
// liuyp 2018年11月28日15: 30: 04
//////////////////////////////////////////////////////////////////////////////
function dcJson() {
    function isCollapsable(arg) {
        return arg instanceof Object && Object.keys(arg).length > 0
    }
    function isUrl(string) {
        var regexp = /^(ftp|http|https): \/\/(\w+: {0,1}\w*@)?(\S+)(: [0-9]+)?(\/|\/([\w#!: .?+=&%@!\-\/]))?/
        return regexp.test(string)
    }
    function json2html(json, options) {
        var html = ''
        if (typeof json === 'string') {
            json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
            if (isUrl(json)) html += '<a href="' + json + '" class="json-string">' + json + '</a>'
            else html += '<span class="json-string">"' + json + '"</span>'
        } else if (typeof json === 'number') {
            html += '<span class="json-literal">' + json + '</span>'
        } else if (typeof json === 'boolean') {
            html += '<span class="json-literal">' + json + '</span>'
        } else if (json === null) {
            html += '<span class="json-literal">null</span>'
        } else if (json instanceof Array) {
            if (json.length > 0) {
                html += '[<ol class="json-array">'
                for (var i = 0; i < json.length; ++i) {
                    html += '<li>'; if (isCollapsable(json[i])) { html += '<a href class="json-toggle"></a>'; }
                    html += json2html(json[i], options); if (i < json.length - 1) { html += ','; } html += '</li>'
                } html += '</ol>]'
            } else {
                html += '[]'
            }
        } else if (typeof json === 'object') {
            var key_count = Object.keys(json).length
            if (key_count > 0) {
                html += '{<ul class="json-dict">'
                for (var key in json) {
                    if (json.hasOwnProperty(key)) {
                        html += '<li>'
                        var keyRepr = options.withQuotes ? '<span class="json-string">"' + key + '"</span>': key
                        if (isCollapsable(json[key])) { html += '<a href class="json-toggle">' + keyRepr + '</a>'; }
                        else { html += keyRepr; }
                        html += ': ' + json2html(json[key], options)
                        if (--key_count > 0) html += ','
                        html += '</li>'
                    }
                }
                html += '</ul>}'
            } else {
                html += '{}'
            }
        }
        return html
    }
    function jsonViewer(self,json,options) {
        try { json = eval('(' + json + ')'); }catch (error) { return alert("Cannot eval JSON: " + error); }
        var html = json2html(json, options)
        if (isCollapsable(json)) html = '<a href class="json-toggle"></a>' + html
        $(self).html(html)
        $(self).off('click')
        $(self).on('click', 'a.json-toggle', function() {
            var target = $(this).toggleClass('collapsed').siblings('ul.json-dict, ol.json-array')
            target.toggle()
            if (target.is(':visible')) { target.siblings('.json-placeholder').remove(); }
            else { var count = target.children('li').length; var placeholder = count + (count > 1 ? ' items': ' item'); target.after('<a href class="json-placeholder">' + placeholder + '</a>'); }
            return false
        })
        $(this).on('click', 'a.json-placeholder', function() {
            $(this).siblings('a.json-toggle').click()
            return false
        })
        if (options.collapsed == true) { $(self).find('a.json-toggle').click();$(self).find('a.json-toggle:first').click(); }
    }
    function _Object_typeof(obj){
        if(obj==null){ return String( obj) }
        var type=Object.prototype.toString.call(obj)||"[object Object]";
        return type.replace("[object ","").replace("]","").toLowerCase();
    }
    function _Object_negative(str) {
        if( ! str ){ return false }
        if( typeof str == "string"){ return !( str == "0" || str == "false" || str == "disable" || str == "null" || str == "undefined" ); }
        if( typeof str == "boolean"){ return str }
        if( typeof str == "number"){ return !!str }
        return false
    }
    return {
        restrict: 'E',
        replace: true,
        template: '<!-- JSON格式化 by liu --><pre class="jsonRenderer"></pre>',
        scope: { json: '=' },
        link: function(scope, element, attrs) {
            scope.$watch("json",function(n,o){
                var jsn = _Object_typeof(n) == "string"? n: JSON.stringify(n);
                if(jsn && jsn != "{}")
                jsonViewer($(element), jsn, { collapsed: _Object_negative(attrs.collapsed)/*默认折叠*/, withQuotes: true/*key用双引号包裹*/ })
            },true)
        }
    }
}
exports = module.exports = dcJson;